package com.turing.customer.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import com.turing.customer.entity.*;
import com.turing.customer.feign.AuthService;
import com.turing.customer.feign.MerchantService;
import com.turing.customer.feign.SystemService;
import com.turing.customer.mapper.*;
import com.turing.customer.service.CustomerService;
import enums.ErrorCode;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import result.Result;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * @author Lenovo
 * @description 针对表【customer(客户表)】的数据库操作Service实现
 * @createDate 2023-04-10 15:14:50
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer>
        implements CustomerService {

    @Resource
    private AuthService authService;
    @Resource
    private LivenessMapper livenessMapper;
    @Resource
    private StatisticsMapper statisticsMapper;
    @Resource
    private SignEverydayMapper signEverydayMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private ConcernMapper concernMapper;
    @Resource
    private HttpServletRequest request;
    @Resource
    private TitlesMapper titlesMapper;
    @Resource
    private SystemService systemService;
    @Resource
    private MerchantService merchantService;
    @Resource
    private CustomerWithdrawalsMapper customerWithdrawalsMapper;


    @Override
    public Result customerLogin(String cusNickname, String cusImg, String openId) {
        LambdaQueryWrapper<Customer> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Customer::getOpenid, openId);
        Customer cus = getOne(wrapper);
        Boolean createCus = false;
        if (cus == null) {
            createCus = true;
            //第一次登录系统 创建用户
            cus = new Customer();
            cus.setCusId(UUID.randomUUID().toString());
            cus.setCusNickname(cusNickname);
            cus.setOpenid(openId);
            cus.setCusImg(cusImg);
            if (!save(cus)) {
                return Result.fail(ErrorCode.ERROR_CREATE_USER);
            }
        } else {
            //判断账户状态
            if (cus.getCusState().intValue() == 1) {
                return Result.fail(ErrorCode.ERROR_USER_LOCKED);
            }
            //尝试更新用户信息
            if (StringUtils.isNotBlank(cusNickname) || StringUtils.isNotBlank(cusImg)) {
                cus.setCusNickname(cusNickname);
                cus.setCusImg(cusImg);
                if (!updateById(cus)) {
                    return Result.fail(ErrorCode.ERROR_UPDATE_USER);
                }
            }
        }
        //得到token
        String token = authService.createTokenByOpenId(cus.getCusId()).getData().toString();
        cus.setToken(token);
        //维护活跃统计表
        LambdaQueryWrapper<Liveness> lvWra = new LambdaQueryWrapper<>();
        lvWra.eq(Liveness::getCusId, cus.getCusId())
                .eq(Liveness::getLivenessDate, new Date());
        Liveness liveness = livenessMapper.selectOne(lvWra);
        if (liveness == null) {
            //今天第一次登录
            liveness = new Liveness();
            liveness.setLivenessId(UUID.randomUUID().toString());
            liveness.setCusId(cus.getCusId());
            liveness.setLivenessDate(new Date());
            liveness.setLivenessCount(1);
            livenessMapper.insert(liveness);
        } else {
            liveness.setLivenessCount(liveness.getLivenessCount() + 1);
            livenessMapper.updateById(liveness);
        }
        //维护登录统计表
        LambdaQueryWrapper<Statistics> stWra = new LambdaQueryWrapper<>();
        stWra.eq(Statistics::getStatisticsDate, new Date());
        Statistics st = statisticsMapper.selectOne(stWra);
        if (st == null) {
            //今天第一次统计
            st = new Statistics();
            st.setStatisticsDate(new Date());
            st.setStatisticsId(UUID.randomUUID().toString());
            st.setTodateCus(createCus ? 1 : 0);
            st.setTodateLog(1);
            statisticsMapper.insert(st);
        } else {
            st.setTodateCus(st.getTodateCus() + (createCus ? 1 : 0));
            st.setTodateLog(st.getTodateLog() + 1);
            statisticsMapper.updateById(st);
        }
        return Result.success(cus);
    }

    @Override
    public Result liveDay(String day1) {
        Map<String, Object> map = super.baseMapper.liveDay(day1);
        if (map != null) {
            return Result.success(map);
        } else {
            Map<String, Object> map1 = new HashMap<>(6);
            map1.put("incrCount", 0);
            map1.put("visitCount", 0);
            map1.put("signCount", 0);
            map1.put("liveCount", 0);
            map1.put("totalCount", 0);
            map1.put("merchantCount", 0);
            return Result.success(map1);
        }
    }



    @Override
    public Result liveMonth(String mth, Integer count) throws ParseException {
        List<Integer> incrList = null;
        //将传过来的月份进行转换
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        //生成日历
        Calendar calendar = Calendar.getInstance();
        //将传过来的日期赋值
        calendar.setTime(sdf.parse(mth));
        List<String> monthList = new ArrayList<>();
        monthList.add(sdf.format(calendar.getTime()));
        for (int i = 0; i < count - 1; i++) {
            //将日期减少一个月
            calendar.add(Calendar.MONTH, -1);
            //最后重新赋值
            monthList.add(sdf.format(calendar.getTime()));
        }
        //新增用户集合
        incrList = statisticsMapper.selectStatistics(monthList);

        //签到用户集合
        List<Integer> signList = null;
        signList = signEverydayMapper.selectSignEveryday(monthList);

        //活跃用户集合
        List<Integer> liveList = null;
        liveList = livenessMapper.selectLiveness(monthList);

        //登录用户集合
        List<Integer> loginList = null;
        loginList = super.baseMapper.selectCustomer(monthList);

        Map<String, Object> map = new HashMap<>();
        map.put("incrList", incrList);
        map.put("signList", signList);
        map.put("liveList", liveList);
        map.put("loginList", loginList);
        return Result.success(map);
    }

    @Override
    public Result cusEdit(JSONObject jsonObject) {
        Customer customer = JSONObject.toJavaObject(jsonObject, Customer.class);
        int i = super.baseMapper.updateById(customer);
        if (i > 0) {
            return Result.success(i);
        } else {
            return Result.fail(0, "添加失败");
        }
    }

    @Override
    public Result geCusById(String id) {
        Map<String, Object> map = super.baseMapper.geCusById(id);
        if (map != null) {
            return Result.success(map);
        } else {
            return Result.fail(0, "无数据");
        }
    }

    @Override
    public Result cusList(String cusNickname, String cusInfo, Integer sortType, Integer orderType, Integer pageNum, Integer pageSize) {
        List<String> merIds = new ArrayList<>();
        Map redisData = new HashMap();
        ZSetOperations zsetOps = redisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple> redisSet;
        if (sortType == 2) {
            if (pageNum != null) {
                if (orderType == 1) {
                    redisSet = zsetOps.reverseRangeWithScores("cusComments", (pageNum - 1) * pageSize, pageNum * pageSize - 1);
                } else {
                    redisSet = zsetOps.rangeWithScores("cusComments", (pageNum - 1) * pageSize, pageNum * pageSize - 1);
                }
            } else {
                if (orderType == 1) {
                    redisSet = zsetOps.reverseRangeWithScores("cusComments", 0, -1);
                } else {
                    redisSet = zsetOps.rangeWithScores("cusComments", 0, -1);
                }
            }
            for (ZSetOperations.TypedTuple typedTuple : redisSet) {
                merIds.add((String) typedTuple.getValue());
            }
        } else {
            redisSet = zsetOps.rangeWithScores("cusComments", 0, -1);
            for (ZSetOperations.TypedTuple typedTuple : redisSet) {
                redisData.put(typedTuple.getValue(), typedTuple.getScore());
            }
        }
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<Map<String, Object>> list = super.baseMapper.cusList(cusNickname, cusInfo, sortType, orderType);
        if (sortType != 2) {
            for (Map<String, Object> map : list) {
                map.put("cusComments", redisData.get(map.get("cusId")));
            }
        }
        if (list.size() == 0) {
            return Result.fail(ErrorCode.NODATA);
        }
        return Result.success(new PageInfo<>(list));
    }

    @Override
    public Result cusCenter(String cusId) {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        token = token.substring(tokenHead.length());

        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token);
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject.getString("username");
        List<Map> list1 = new ArrayList<>();
        List<Map> list = super.baseMapper.cusCenter(cusId, username);
        for (Map map : list) {
            String cusId1 = (String) map.get("cusId");
            String titlesId = super.baseMapper.selectById(cusId1).getTitlesId();
            List<String> titles = titlesMapper.selectByList(titlesId);
            map.put("titlesImg",titles);
            list1.add(map);
        }
        if (list1.size() > 0) {
            return Result.success(list1);
        } else {
            return Result.fail(0, "无数据");
        }
    }

    @Override
    public Result rankList(Integer orderType, Integer pageNum, Integer pageSize) {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        token = token.substring(tokenHead.length());
        //System.out.println("token = " + token);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token);
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject.getString("username");
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<Map> list  = super.baseMapper.rankList(orderType, username);
        if (list.size() > 0) {
            if (pageNum != null && pageSize != null){
                return Result.success(new PageInfo<>(list));
            }else {
                return Result.success(list);
            }
        } else {
            return Result.fail(0, "无数据");
        }
    }


    @Override
    public Result myWallet() {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        String token1 = token.substring(tokenHead.length());
        //System.out.println("token = " + token1);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token1);
        JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject1.getString("username");

        //通过字典详情接口获取到 dicInfo （单次提现最高金额，服务提成）
        JSONObject restrict1 = JSON.parseObject(JSON.toJSONString(systemService.getDic("4", "单次提现最高金额").getData()));
        Double restrict = restrict1.getDouble("dicInfo");
        JSONObject servicePoint1 = JSON.parseObject(JSON.toJSONString(systemService.getDic("5", "服务提成").getData()));
        Double servicePoint = servicePoint1.getDouble("dicInfo");

        //通过客户已提现金额接口获取到 已提现金额（cw_value）
        Result cusTakeIn = systemService.getCusTakeIn(token);
        String s = cusTakeIn.getData().toString();
        System.out.println("s = " + s);
//        String jsonString = JSON.toJSONString(systemService.getCusTakeIn(token));
//        JSONObject jsonObject = JSON.parseObject(jsonString);

//        Double cashOut = jsonObject.getDouble("cw_value");

        double v = Double.parseDouble(s);
        //总赏金
        Map<String,Object> map = super.baseMapper.myWallet(username);
        System.out.println("map = " + map);
        if (map.get("cusAmount") == null) {
            map.remove("liyang");
            map.put("cusAmount", 0);
        }
        map.remove("liyang");
        map.put("restrict",restrict);
        map.put("servicePoint",servicePoint);
        map.put("cashOut",v);
        if (map.isEmpty()){
            return Result.fail(0,"无数据");
        }else {
            return Result.success(map);
        }
    }

    @Override
    public Result cusPay(JSONObject jsonObject) throws ParseException {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        token = token.substring(tokenHead.length());
        //System.out.println("token = " + token);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token);
        JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject1.getString("username");

        String merchantId = jsonObject.getString("merchantId");
        Double cost = jsonObject.getDouble("cost");
        String longitude = jsonObject.getString("longitude");
        String latitude = jsonObject.getString("latitude");

        Customer customer = super.baseMapper.selectById(username);

        Merchant merchant = JSONObject.toJavaObject(jsonObject,Merchant.class);

        //买单者不可为商家店长或管理员
        Result merById = merchantService.adminList(merchant.getMerchantId(),null,null,null,null,null,null);
        JSONObject jsonObject5 = JSON.parseObject(JSON.toJSONString(merById.getData()));
        String keeper = jsonObject5.getJSONObject("keeper").getString("cusId");
        JSONArray adminList = jsonObject5.getJSONArray("adminList");
        System.out.println("keeper = " + keeper);
        System.out.println("adminList = " + adminList);
        for (int i = 0; i < adminList.size(); i++) {
            JSONObject object = adminList.getJSONObject(i);
            String cusId = object.getString("cusId");
            System.out.println("cusId = " + cusId);
            if (cusId.contains(username) || keeper.equals(username)){
                System.out.println("我进来了");
                return Result.fail(0,"买单者不可为商家店长或管理员");
            }
        }

        //需要判断客户余额是否足够
        System.out.println("username = " + username);
        BigDecimal cusAmount = customer.getCusAmount();
        System.out.println("cusAmount = " + cusAmount);
        Double value = Double.valueOf(String.valueOf(cusAmount));
        if(value != null){
            System.out.println("value = " + value);
            if (value < cost.doubleValue()){
                System.out.println("我到了！");
                return Result.fail(0, "客户余额不足");
            }
        }

        //判断客户今日消费总额(通过"客官付"支出的总额)是否超出客官付
        //获取客官付每日上限
        JSONObject restrict1 = JSON.parseObject(JSON.toJSONString(systemService.getDic("12", "客官付每日上限").getData()));
        System.out.println("restrict1 = " + restrict1);
        Double restrict = restrict1.getDouble("dicInfo");
        System.out.println("restrict = " + restrict);
        //获取今日所有消费
        LocalDate today = LocalDate.now();
        CustomerWithdrawals customerWithdrawals =  customerWithdrawalsMapper.selectToday(today);
        System.out.println("customerWithdrawals = " + customerWithdrawals);
        BigDecimal cwValue = customerWithdrawals.getCwValue();
        Double aDouble = Double.valueOf(String.valueOf(cwValue));
        Date cwCreateTime = customerWithdrawals.getCwCreateTime();
        System.out.println("aDouble = " + aDouble);
        System.out.println("cwValue = " + cwValue);
        System.out.println("cwCreateTime = " + cwCreateTime);

        if(aDouble + cost > restrict){
            return Result.fail(0,"客户今日消费总额已超出客官付每日上限");
        }


        //商家与客户的距离不能超过500米
        Double doubles = super.baseMapper.selectDistance(merchantId,longitude,latitude,username);
        System.out.println("list = " + doubles);
        if (doubles != null){
            if (doubles >= 500){
                System.out.println("我刚来");
                return Result.fail(0,"商家与客户的距离不能超过500米");
            }
        }

        //商家余额不能低于最低限额
        //商家余额
        JSONObject merchantBalance = JSON.parseObject(JSON.toJSONString(merchantService.getMerById(merchantId).getData()));
        System.out.println("merchantBalance = " + merchantBalance);
        Double totalAmount = merchantBalance.getDouble("totalAmount");
        System.out.println("totalAmount = " + totalAmount);
        Double sendAmount = merchantBalance.getDouble("sendAmount");
        System.out.println("sendAmount = " + sendAmount);
        Double jieguo = totalAmount - sendAmount;
        System.out.println("jieguo = " + jieguo);
        //最低限额
        JSONObject minimumLimit = JSON.parseObject(JSON.toJSONString(systemService.getDic("11", "客官付商家最低额度").getData()));
        System.out.println("minimumLimit = " + minimumLimit);
        Double minimum = minimumLimit.getDouble("dicInfo");
        System.out.println("minimum = " + minimum);
        if (jieguo < minimum){
            return Result.fail(0,"商家余额不能低于最低限额");
        }

        System.out.println("-----------------");
        //商家流水的kwInfo为"客官付收款
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("kwInfo","客官付收款");
        jsonObject2.put("targetId",merchantId);
        jsonObject2.put("sourceId",username);
        jsonObject2.put("kwValue",cost);
        jsonObject2.put("kwType",0);
        jsonObject2.put("kwCreateTime",new Date());
        System.out.println("jsonObject2 = " + jsonObject2);
        systemService.kwAddSave(jsonObject2);
        //客户流水的cwInfo为"客官付支出
        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.put("cwInfo","客官付支出");
        jsonObject3.put("targetId",merchantId);
        jsonObject3.put("sourceId",customer.getCusId());
        jsonObject3.put("cwType",0);
        jsonObject3.put("cwValue",cost);
        jsonObject3.put("cwCreateTime",new Date());
        System.out.println("jsonObject3 = " + jsonObject3);
        systemService.cwAddSave(jsonObject3);
        //给店长及商家管理员发站内信
        JSONObject jsonObject4 = new JSONObject();
        jsonObject4.put("messageTitle","客官付到账");
        jsonObject4.put("messageContent","用户" + customer.getCusNickname() + "成功支付" + cost);
        jsonObject4.put("startTime",new Date());
        jsonObject4.put("endTime",new Date());
        jsonObject4.put("messageType",0);
        System.out.println("jsonObject4 = " + jsonObject4);
        systemService.addSave(jsonObject4);
        //修改客户花费之后的赏金
        BigDecimal amount = super.baseMapper.selectById(username).getCusAmount();
        BigDecimal cost1 = new BigDecimal(Double.toString(cost));
        customer.setCusAmount(amount.subtract(cost1));
        super.baseMapper.updateById(customer);
        return Result.success();
    }

    @Override
    public Result likeList(String cusId, Integer pageNum, Integer pageSize) {
        if (pageNum != null && pageSize != null){
            PageHelper.startPage(pageNum,pageSize);
        }
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        String token1 = token.substring(tokenHead.length());
        //System.out.println("token = " + token1);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token1);
        JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject1.getString("username");
        List<Map> list = super.baseMapper.likeList(cusId,username);
        if (list.size() > 0){
            return Result.success(new PageInfo<>(list));
        }else {
            return Result.fail(0,"无数据");
        }

    }

    @Override
    public Result cnSave(String cusId) {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        token = token.substring(tokenHead.length());
        //System.out.println("token = " + token);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token);
        JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject1.getString("username");



        



        return null;



    }

    @Override
    public Result cusListByCusIds(String[] ids) {
        //获取token
        String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        token = token.substring(tokenHead.length());
        //System.out.println("token = " + token);
        //根据token获取id
        Result infoByToken = authService.getUserInfoByToken(token);
        JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(infoByToken.getData()));
        String username = jsonObject1.getString("username");
        List<Map> list = super.baseMapper.cusListByCusIds(ids,username);
        if (list.size() == 0){
            return Result.fail(ErrorCode.NODATA);
        }
        return Result.success(list);
    }
}




